package com.tarena.tp.luban.worker.server.manager;


import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.tarena.passport.protocol.LoginUser;
import com.tarena.passport.sdk.context.SecurityContext;
import com.tarena.tp.attach.server.client.AttachApi;
import com.tarena.tp.attach.server.dto.AttachDTO;
import com.tarena.tp.attach.server.param.AttachUpdateParam;
import com.tarena.tp.attach.server.query.AttachQuery;
import com.tarena.tp.luban.account.server.client.AccountApi;
import com.tarena.tp.luban.account.server.dto.AccountDTO;
import com.tarena.tp.luban.worker.server.bo.*;
import com.tarena.tp.luban.worker.server.common.config.IdCardConfig;
import com.tarena.tp.luban.worker.server.common.constant.GlobalConstant;
import com.tarena.tp.luban.worker.server.common.enums.AuditStatusEnum;
import com.tarena.tp.luban.worker.server.common.enums.IdCardEnum;
import com.tarena.tp.luban.worker.server.common.enums.ResultEnum;
import com.tarena.tp.luban.worker.server.common.util.Base64Util;
import com.tarena.tp.luban.worker.server.common.util.ByteStreamFromURL;
import com.tarena.tp.luban.worker.server.common.util.DateUtil;
import com.tarena.tp.luban.worker.server.common.util.HttpUtil;
import com.tarena.tp.luban.worker.server.dto.param.*;
import com.tarena.tp.luban.worker.server.repository.AuditLogRepository;
import com.tarena.tp.luban.worker.server.repository.WorkerAreaRepository;
import com.tarena.tp.luban.worker.server.repository.WorkerCategoryRepository;
import com.tarena.tp.luban.worker.server.repository.WorkerRepository;
import com.tedu.inn.commons.utils.Asserts;
import com.tedu.inn.protocol.exception.BusinessException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

@Slf4j
@Service
public class WorkerService {
    @Resource
    private WorkerRepository workerRepository;

    @Resource
    private WorkerAreaRepository workerAreaRepository;

    @Resource
    private WorkerCategoryRepository workerCategoryRepository;

    @Resource
    private AuditLogRepository auditLogRepository;

    @Resource
    private AttachApi attachApi;

    @Resource
    private IdCardConfig idCardConfig;


    @Value("${url}")
    private String url;

    @Value("${app.business.type}")
    private Integer businessType;

    @Autowired
    private AccountApi accountApi;


    /**
     * 身份认证
     */
    public IdCardBO checkIdCard(List<IdCardParam> idCardParams) throws BusinessException{
        IdCardBO cardBO = new IdCardBO();
        try {
            List<IdCardParam> collect = idCardParams.stream().filter(id -> IdCardEnum.FRONT.getValue().equals(id.getType())).collect(Collectors.toList());
            if(!CollectionUtils.isEmpty(collect)) {
                IdCardParam idCardParam = collect.get(0);
                byte[] imgData = ByteStreamFromURL.getByteStreamFromURL(idCardParam.getURL());//
                String imgStr = Base64Util.encode(imgData);
                String imgParam = URLEncoder.encode(imgStr,"UTF-8");
                String param = "id_card_side="+"front"+"&image="+imgParam;
                String result = HttpUtil.post(idCardConfig.getUrl(),idCardConfig.getToken(),param);
                log.info("result={}", JSONObject.toJSONString(result));
                JSONObject jsonObject= JSON.parseObject(result);
                String wordsStr  = JSONObject.toJSONString(jsonObject.get("words_result"));
                JSONObject wordsResultJson=JSONObject.parseObject(wordsStr);
                if(wordsResultJson.size()!=0){
                    if(idCardParam.getType() == IdCardEnum.FRONT.getValue()){
                        String userNameStr = JSONObject.toJSONString(wordsResultJson.get("姓名"));
                        JSONObject userNameJson  = JSON.parseObject(userNameStr);
                        String idCardStr = JSONObject.toJSONString(wordsResultJson.get("公民身份号码"));
                        JSONObject idCardJson = JSON.parseObject(idCardStr);
                        cardBO.setValid(true);
                        cardBO.setCardNo(String.valueOf(idCardJson.get("words")));
                        cardBO.setRealName(String.valueOf(userNameJson.get("words")));
                    }
                    if(idCardParam.getType()==IdCardEnum.BACK.getValue()){
                        String userCardTimeStr = JSONObject.toJSONString(wordsResultJson.get("失效日期"));
                        JSONObject userCardTimeJson = JSON.parseObject(userCardTimeStr);
                        String userCardTime = String.valueOf(userCardTimeJson.get("words"));
                        if(userCardTime.compareTo(DateUtil.getDateStr(new Date(), GlobalConstant.FORMATE_TYPE))>0){
                            cardBO.setValid(true);
                        }
                    }
                }
            }
            //只需要一个字节流  根据 URL 获取字节流
            return cardBO;
        }catch(Exception e){
            throw new BusinessException(ResultEnum.ID_CARD_VERIFY_FAILED);
        }
    }

    @Transactional(rollbackFor = Exception.class)
    public Long create(WorkerCreateParam workerCreateParam) throws BusinessException {
        workerCreateParam.setUserId(getUserIdByToken());
        IdCardBO idCardBO = checkIdCard(workerCreateParam.getAttachList());
        Asserts.isTrue(idCardBO == null,new BusinessException(ResultEnum.ID_CARD_VERIFY_FAILED));
        Asserts.isTrue(!idCardBO.isValid(),new BusinessException(ResultEnum.ID_CARD_VERIFY_FAILED));
        //身份信息对比
        //if (!workerCreateParam.getRealName().equals(idCardBO.getRealName()) ||
        //        !workerCreateParam.getIdCard().equals(idCardBO.getCardNo())) {
        //    throw new BusinessException(ResultEnum.ID_CARD_VERIFY_FAILED);
        //}
        //保存用户
        Long userId = workerCreateParam.getUserId();
        Long id = saveWorker(userId, workerCreateParam);
        //保存区域信息和品类信息 //todo 循环插入后续优化为 批量插入
        saveArea(userId,workerCreateParam.getWorkerAreaParams());
        saveCategory(userId,workerCreateParam.getWorkerCategoryParams());
        return id;
    }

    private Long saveWorker(Long userId,WorkerCreateParam workerCreateParam) throws BusinessException {
        workerRepository.delete(userId);
        Long id = workerRepository.save(workerCreateParam);
        //身份证图片的存储
        try{
            createAttach(id.intValue(),workerCreateParam.getAttachList());
        }catch (Exception e){
            throw new BusinessException(ResultEnum.ATTACH_FAILED);
        }
        return id;
    }

    private void saveArea(Long userId,List<WorkerAreaParam> workerAreaParams){
        workerAreaRepository.deleteByUserId(userId);
        if (!CollectionUtils.isEmpty(workerAreaParams)) {
            workerAreaParams.forEach(param->{
                param.setUserId(userId);
                workerAreaRepository.saveWorkerArea(param);
            });
        }
    }

    private void saveCategory(Long userId,List<WorkerCategoryParam> workerCategoryParams){
        workerCategoryRepository.deleteByUserId(userId);
        if (!CollectionUtils.isEmpty(workerCategoryParams)) {
            workerCategoryParams.forEach(param->{
                param.setUserId(userId);
                workerCategoryRepository.saveCategoryWorker(param);
            });
        }
    }

    private void createAttach(Integer businessId, List<IdCardParam> cardParams) {
        List<AttachUpdateParam> attachUpdateParams=new ArrayList<>();
        //fileIds  文件 id  前端入参
        cardParams.forEach(param ->{
            AttachUpdateParam updateParam = new AttachUpdateParam();
            updateParam.setId(param.getId());
            updateParam.setIsCover(param.getType());
            updateParam.setBusinessId(businessId);
            updateParam.setBusinessType(businessType);
            attachUpdateParams.add(updateParam);
        });
        attachApi.batchUpdateAttachByIdList(attachUpdateParams);
    }

    private List<AttachInfoBO> getAttachList(Long businessId) throws BusinessException{
        try {
            AttachQuery attachQuery = new AttachQuery();
            attachQuery.setBusinessId(businessId.intValue());
            attachQuery.setBusinessType(businessType);
            List<AttachDTO> attachList = attachApi.getAttachInfoByParam(attachQuery);
            List<AttachInfoBO> result = new ArrayList<>();
            if (!CollectionUtils.isEmpty(attachList)) {
                attachList.forEach(attach -> {
                    AttachInfoBO attachInfoBO = new AttachInfoBO();
                    attachInfoBO.setUrl(url + attach.getFileUuid());
                    result.add(attachInfoBO);
                });
            }
            return result;
        }catch (Exception e) {
            throw new BusinessException(ResultEnum.ATTACH_FAILED);
        }
    }

    private Long getUserIdByToken() throws BusinessException {
        LoginUser loginUser = SecurityContext.getLoginToken();
        log.info("current-user:{}",loginUser);
        Asserts.isTrue(loginUser == null,new BusinessException(ResultEnum.USER_TOKEN_VERIFY_FAILED));
        return loginUser.getUserId();
    }

    public WorkerBO getWorkerDetail() throws BusinessException{
        Long workerId = getUserIdByToken();
        WorkerBO workerBO = workerRepository.getWorker(workerId);
        if (workerBO.getUserId() != null) {
            //查询区域
            List<WorkerAreaBO> workerArea = getWorkerArea(workerBO.getUserId());
            workerBO.setWorkerAreaBOList(workerArea);
            //查询服务品类
            List<WorkerCategoryBO> workerCategory = getWorkerCategory(workerBO.getUserId());
            workerBO.setWorkerCategoryBOList(workerCategory);
            //查询附件
            List<AttachInfoBO> attachList = getAttachList(workerBO.getId());
            workerBO.setAttachInfoBOList(attachList);
            //查询账户
            AccountBO account = getAccount(workerId);
            workerBO.setAccountBO(account);
            Integer auditStatus = workerBO.getAuditStatus();
            //审核未通过
            if (AuditStatusEnum.REJECTED.getValue().equals(auditStatus)) {
                workerBO.setRejectReason(getRejectReason(workerId));
            }
            return workerBO;
        }
        //用户首次登陆workerBO为空对象，设置auditStatus =3 表示未发起审核，未注册师傅。
        workerBO.setAuditStatus(AuditStatusEnum.UNCREATED.getValue());
        return workerBO;
    }

    private List<WorkerCategoryBO> getWorkerCategory(Long userId){
        return workerCategoryRepository.
                getWorkerCategoryByWorkerId(userId);
    }

    private List<WorkerAreaBO> getWorkerArea(Long userId) {
        return workerAreaRepository.
                getWorkerAreaByWorkerId(userId);
    }

    private AccountBO getAccount(Long userId){
        AccountDTO account = accountApi.getAccountByUserId(userId);
        AccountBO accountBO = new AccountBO();
        if (account != null) {
            accountBO.setTotalAmount(account.getTotalAmount());
        }else {
            accountBO.setTotalAmount(0L);
        }
        return accountBO;
    }


    private String getRejectReason(Long workerId){
        //todo 可以用sql 直接实现
        List<AuditBO> audit = auditLogRepository.getAudit(workerId);
        if (!CollectionUtils.isEmpty(audit)) {
            List<AuditBO> collect = audit.stream().filter(auditBO ->
                            AuditStatusEnum.REJECTED.getValue().equals(auditBO.getAuditStatus()))
                    .sorted((o1, o2) -> o2.getId().compareTo(o1.getId()))
                    .collect(Collectors.toList());
            if (!CollectionUtils.isEmpty(collect)) {
                AuditBO auditBO = collect.get(0);
                if (auditBO != null) {
                    return auditBO.getRejectReason();
                }
            }
        }
        return "";
    }
}



















